package fem2.material.cohesive_law2;

import fem2.Element;
import fem2.element.crack_sda2.SDAElement;
import inf.jlinalg.Array2DMatrix;
import inf.jlinalg.ArrayVector;
import inf.jlinalg.IMatrix;
import inf.jlinalg.IVector;

/**
 * cohesive law for pure Mode 1 opening with linear law for crack propagation
 * tracking
 * 
 * @author hbui
 * 
 */
public class LinearCohesiveLaw extends CohesiveLaw {

	private double H;
	private double km1;
	private double km2;

	/**
	 * if one km is provided, it's a linear cohesive law. If two are provided,
	 * it's 3d law. Please be careful.
	 * 
	 * @param Gf
	 * @param ft
	 * @param km
	 */
	public LinearCohesiveLaw(double Gf, double ft, double km) {
		super(Gf, ft);
		H = -Math.pow(ft, 2) / (2 * Gf);
		this.km1 = km;
		this.km2 = km;
	}

	/**
	 * if one km is provided, it's a linear cohesive law. If two are provided,
	 * it's 3d law. Please be careful.
	 * 
	 * @param Gf
	 * @param ft
	 * @param km1
	 * @param km2
	 */
	public LinearCohesiveLaw(double Gf, double ft, double km1, double km2) {
		super(Gf, ft);
		H = -Math.pow(ft, 2) / (2 * Gf);
		this.km1 = km1;
		this.km2 = km2;
	}

	@Override
	public IVector getJumpTraction(Element e, int k) {
		int dim = e.getMeshPart().getDimension();
		IVector w = ((SDAElement) e).getCrackOpeningParameter();
		if (dim == 2) {
			double tn = ft + H * w.get(0);
			double tm = km1 * w.get(1);
			return new ArrayVector(tn, tm);
		} else if (dim == 3) {
			double tn = ft + H * w.get(0);
			double tm1 = km1 * w.get(1);
			double tm2 = km2 * w.get(2);
			return new ArrayVector(tn, tm1, tm2);
		} else {
			throw new Error("invalid dimension");
		}
	}

	@Override
	public IMatrix getJumpStiffness(Element e, int k) {
		int dim = e.getMeshPart().getDimension();
		if (dim == 2) {
			double[][] C = new double[][] { { H, 0.0 }, { 0.0, km1 } };
			return new Array2DMatrix(C);
		} else if (dim == 3) {
			double[][] C = new double[][] { { H, 0.0, 0.0 }, { 0.0, km1, 0.0 }, { 0.0, 0.0, km2 } };
			return new Array2DMatrix(C);
		} else {
			throw new Error("invalid dimension");
		}
	}

	@Override
	public void InitializeSolutionStep(Element e) {
	}

	@Override
	public void InitalizeNonlinearIteration(Element e) {
	}

	@Override
	public void FinalizeNonlinearIteration(Element e) {
	}

	@Override
	public void FinalizeSolutionStep(Element e) {
	}

	@Override
	public void CalculateOutputData(Element e) {
	}
}
